﻿using CodingWiki_DataAccess.FluentConfig;
using CodingWiki_Model.Models;
using CodingWiki_Model.Models.FluentModels;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CodingWiki_DataAccess.Data
{
    public class ApplicationDbContext: DbContext
    {
        // add-migration AddBookTodDb   Up 接下来做的 down 恢复回滚

        // update-database  AddBookTodDb 回到之前的数据状态 ，不填就是最新的

        //__EFMigrationsHistory 这个生成的表 应用于 迁移跟踪数据

        //remove-migration 删除迁移             migrationBuilder.DropTable("Genres");

        //get-migration 获取 所有迁移

        //drop-database 删除数据库 再update-database 又可以恢复

        //不删除 迁移文件 除非你知道迁移做什么才删，因为updatebase 也可以继续调用的他存在的


        //可以 add-migration 创建一个空的 然后自己写 up   migrationBuilder.Sql ("@ Create Procexxxxxx");  down  migrationBuilder.Sql("Delete xxxxxx");          
        
        public DbSet<Book> Books { get; set; }
        public DbSet<Category> Categories { get; set; }
        public DbSet<Author> Authors { get; set; }
        public DbSet<SubCategory> SubCategories { get; set; }
        public DbSet<Publisher> Publishers { get; set; }
        
        public DbSet<BookAuthorMap> BookAuthorMaps { get; set; }
        public DbSet<BookDetail> BookDetails { get; set; }


        public DbSet<Fluent_BookDetail> BookDetail_fluent { get; set; }
        public DbSet<Fluent_Book> Fluent_Books { get; set; }
        public DbSet<Fluent_Author> Fluent_Authors { get; set; }
        public DbSet<Fluent_Publisher> Fluent_Publishers { get; set; }
        public DbSet<Fluent_BookAuthorMap> Fluent_BookAuthorMaps { get; set; }
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
        {
        }

        protected override void OnConfiguring(DbContextOptionsBuilder options)
        {
            //var fileLogger = new StreamWriter("./EFlog/efcore.log", true); // "true" 表示追加到文件而不是覆盖

            //options.UseSqlServer("Server=YMax\\SQLEXPRESS;Database=CodingWiki;Trusted_Connection=True;TrustServerCertificate=true")
            //    .LogTo(Console.WriteLine, new[] { DbLoggerCategory.Database.Command.Name }, LogLevel.Information);
                //.LogTo(fileLogger.WriteLine, LogLevel.Information).EnableSensitiveDataLogging(); ;
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            #region Fluent
            //modelBuilder.Entity<Fluent_BookDetail>().ToTable("Fluent_BookDetails");// 表名
            //modelBuilder.Entity<Fluent_BookDetail>().Property(u => u.NumberOfChapters).HasColumnName("NoOfhapters");//列名
            //modelBuilder.Entity<Fluent_BookDetail>().Property(u => u.NumberOfChapters).IsRequired(); //必须
            //modelBuilder.Entity<Fluent_BookDetail>().HasKey(u => u.BookDetail_Id);//主键
            //modelBuilder.Entity<Fluent_BookDetail>().HasOne(u => u.Book).WithOne(b=>b.BookDetail)
            //    .HasForeignKey<Fluent_BookDetail>(u=>u.Book_Id); //1:1

            //modelBuilder.Entity<Fluent_Book>().Property(u => u.ISBN).HasMaxLength(50);
            //modelBuilder.Entity<Fluent_Book>().Property(u => u.ISBN).IsRequired();
            //modelBuilder.Entity<Fluent_Book>().HasKey(u => u.BookId);
            //modelBuilder.Entity<Fluent_Book>().Ignore(u => u.PriceRange);
            //modelBuilder.Entity<Fluent_Book>().HasOne(u => u.Publisher).WithMany(u=>u.Books).HasForeignKey(u=>u.Publisher_Id); //1对多

            //modelBuilder.Entity<Fluent_Publisher>().Property(u => u.Name).IsRequired();
            //modelBuilder.Entity<Fluent_Publisher>().HasKey(u => u.Publisher_Id);

            //modelBuilder.Entity<Fluent_Author>().Property(u => u.FirstName).HasMaxLength(50);
            //modelBuilder.Entity<Fluent_Author>().Property(u => u.FirstName).IsRequired();
            //modelBuilder.Entity<Fluent_Author>().Property(u => u.LastName).IsRequired();
            //modelBuilder.Entity<Fluent_Author>().HasKey(u => u.Author_Id);
            //modelBuilder.Entity<Fluent_Author>().Ignore(u => u.FullName);
            
            //modelBuilder.Entity<Fluent_BookAuthorMap>().HasKey(u => new { u.Author_Id, u.Book_Id });
            //modelBuilder.Entity<Fluent_BookAuthorMap>().HasOne(u=>u.Book).WithMany(u=>u.BookAuthorMap).HasForeignKey(u=>u.Book_Id);
            //modelBuilder.Entity<Fluent_BookAuthorMap>().HasOne(u => u.Author).WithMany(u => u.BookAuthorMap).HasForeignKey(u => u.Author_Id);
            #endregion


            modelBuilder.Entity<Book>().Property(u => u.Price).HasPrecision(10, 5); //设置精度 10位数,5位小数点后
            modelBuilder.Entity<BookAuthorMap>().HasKey(u => new { u.Author_Id, u.Book_Id });

            modelBuilder.ApplyConfiguration(new FluentAuthorConfig());
            modelBuilder.ApplyConfiguration(new FluentBookAuthorMapConfig());
            modelBuilder.ApplyConfiguration(new FluentBookConfig());
            modelBuilder.ApplyConfiguration(new FluentBookDetailConfig());
            modelBuilder.ApplyConfiguration(new FluentPublisherConfig());


            //添加数据
            modelBuilder.Entity<Book>().HasData(
                 new Book { BookId = 1, Title = "Spider without Duty", ISBN = "123B12", Price = 10.99m, Publisher_Id = 1 },
                 new Book { BookId = 2, Title = "Fortune of time", ISBN = "12123B12", Price = 11.99m, Publisher_Id = 1 }
             );

            var bookList = new Book[]
            {
                new Book { BookId = 3, Title = "Fake Sunday", ISBN = "77652", Price = 20.99m, Publisher_Id=2 },
                new Book { BookId = 4, Title = "Cookie Jar", ISBN = "CC12B12", Price = 25.99m , Publisher_Id=3},
                new Book { BookId = 5, Title = "Cloudy Forest", ISBN = "90392B33", Price = 40.99m , Publisher_Id=3}
            };
            modelBuilder.Entity<Book>().HasData(bookList);

            modelBuilder.Entity<Publisher>().HasData(
                new Publisher { Publisher_Id = 1, Name = "Pub 1 Jimmy", Location = "Chicago" },
                new Publisher { Publisher_Id = 2, Name = "Pub 2 John", Location = "New York" },
                new Publisher { Publisher_Id = 3, Name = "Pub 3 Ben", Location = "Hawaii" }
                );

            //modelBuilder.Entity<视图>().HasNoKey().ToView("");//只读，用于配置一个不跟踪任何键的视图（View）。这通常用于当你想要从数据库中读取数据，但不需要更新这些数据，或者视图不包含可以作为键的唯一标识符时
        }
    }
}
